using IQIGame.Onigao.Framework;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using UnityEngine;
using static IQIGame.Onigao.Game.INetClientModule;

namespace IQIGame.Onigao.Game
{
    public abstract class CNetHandler
    {
        private readonly Dictionary<int, Package2MessageWrapper> m_cache_function = new();
        private readonly ConcurrentQueue<MessageWrapper> m_responses = new();

        public virtual void Init()
        {
            FrameworkEntry.MonoDriver.updateEvent += ExecuteResponse;
        }

        public virtual void Shutdown()
        {
            FrameworkEntry.MonoDriver.updateEvent -= ExecuteResponse;
            m_cache_function.Clear();
            m_responses.Clear();
        }

        protected bool Add(INetClientModule mod)
        {
            foreach (var kv in mod.GetModuleFunction())
            {
                m_cache_function.Add(kv.Key, kv.Value);
            }
            return true;
        }

        private void ExecuteResponse(float deltaTime, float unScaledDeltaTime)
        {
            while (m_responses.TryDequeue(out MessageWrapper response))
            {
                response.Call();
            }
        }

        public bool ProcessPackage(ISession session, ReceivePackage package)
        {
            if (m_cache_function.TryGetValue(package.Header.Messagid, out var delegetor))
            {
                try
                {
                    MessageWrapper messageResponse = delegetor.Invoke(session, package);
                    m_responses.Enqueue(messageResponse);
                    return true;
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                    throw e;
                }
            }
            else
            {
                Debug.LogWarningFormat("CNetHandler not find module, msgId={0}", package.Header.Messagid);
                return false;
            }
        }

    }
}